package com.jrx.anytxn.accounting.job.glinterface.config;

import com.jrx.anytxn.accounting.bean.GlInterfaceBean;
import com.jrx.anytxn.accounting.config.AnytxnBatchProperties;
import com.jrx.anytxn.accounting.entity.GaVoucherInfo;
import com.jrx.anytxn.accounting.job.glinterface.step.GlInterfaceListener;
import com.jrx.anytxn.accounting.job.glinterface.step.GlInterfaceProcessor;
import com.jrx.anytxn.accounting.job.glinterface.step.GlInterfaceReader;
import com.jrx.anytxn.accounting.job.glinterface.step.GlInterfaceWriter;
import com.jrx.anytxn.accounting.mapper.ext.ExtVoucherInfoMapper;
import com.jrx.anytxn.common.constant.Constants;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.param.entity.PrCodeTable;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.mapper.ext.ExtPrCodeTableMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import com.jrx.anytxn.transaction.entity.TlGlInterfaceInfo;
import org.apache.ibatis.session.SqlSessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.configuration.annotation.JobBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepBuilderFactory;
import org.springframework.batch.core.configuration.annotation.StepScope;
import org.springframework.batch.core.launch.support.RunIdIncrementer;
import org.springframework.batch.core.step.tasklet.Tasklet;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.task.SimpleAsyncTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.Objects;


/**
 * @ClassName GlInterfaceHandle
 *  总账流水处理
 * @author  yf
 * date  2019/9/11 0011
 * @Version V1.0
 **/
@Configuration
@EnableConfigurationProperties(AnytxnBatchProperties.class)
public class GlInterfaceConfiguration {

    @Resource(name = "bizSqlSessionFactory")
    SqlSessionFactory sqlSessionFactory;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private AnytxnBatchProperties anytxnBatchProperties;
    @Resource
    private ExtPrCodeTableMapper extPrCodeTableMapper;
    @Autowired
    private IOrganizationTableService organizationTableService;
    @Autowired
    private GlInterfaceProcessor glInterfaceProcessor;
    @Autowired
    private GlInterfaceWriter glInterfaceWriter;
    @Resource
    Environment environment;
    @Autowired
    private GlInterfaceListener glInterfaceListener;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;
    @Autowired
    private ExtVoucherInfoMapper extVoucherInfoMapper;

    private static final Logger logger = LoggerFactory.getLogger(GlInterfaceConfiguration.class);


    @Bean
    public Job glInterfaceHandleJob() {
        return jobBuilderFactory.get("glInterfaceHandleJob").incrementer(new RunIdIncrementer()).listener(glInterfaceListener)
                .start(glInterfaceHandleStep())
                .next(modifyEntryStep())
                .build();
    }


    @Bean
    public Step modifyEntryStep() {
        return stepBuilderFactory.get("modifyEntryStep")
                .tasklet(modifyEntryTasklet())
                .build();
    }

    @Bean
    public Tasklet modifyEntryTasklet() {
        return (stepContribution, chunkContext) -> {
            try {
                logger.info("传票流水修数");
                String tenantId = Constants.DEFAULT_TENANT_ID;
                //查询应用启动文件参数，确保仅在特定的激活文件中执行
                logger.info("激活的配置文件: {}", Arrays.toString(environment.getActiveProfiles()));
                final String expectedKeywords = "1011";
                boolean expected = Arrays.stream(environment.getActiveProfiles())
                        .anyMatch(x -> x.endsWith(expectedKeywords));
                if (expected) {
                    //获取业务日期
                    PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
                    String businessDate = DateUtils.format(org.getToday());
                    PrCodeTable prCodeTable = extPrCodeTableMapper.selectByTypeIdAndCodeId("MODIFY_DATA_DATE", "impairmentDate", tenantId);
                    if (Objects.nonNull(prCodeTable) && Objects.equals(businessDate, prCodeTable.getCodeName())) {
                        logger.info("传票流水为空，开始修数");
                        extVoucherInfoMapper.modifyEntry(DateUtils.format(org.getToday(),DateUtils.DATE_PATTERN));
                        logger.info("传票流水修数完毕");
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.warn("传票流水修数失败:{}", e.getMessage());
            }
            return RepeatStatus.FINISHED;
        };
    }

    @Bean
    public Step glInterfaceHandleStep() {
        return stepBuilderFactory.get("glInterfaceHandleStep")
                .<TlGlInterfaceInfo, GlInterfaceBean>chunk(anytxnBatchProperties.getGlInterfaceConfig().getChunkLimit())
                .reader(glInterfaceHandleReader())
                .processor(glInterfaceProcessor)
                .writer(glInterfaceWriter)
                .transactionManager(platformTransactionManager)
                .taskExecutor(new SimpleAsyncTaskExecutor())
                .throttleLimit(anytxnBatchProperties.getGlInterfaceConfig().getThrottleLimit())//多线程*/
                .build();

    }

   /* @Bean
    @StepScope
    public SynchronizedItemStreamReader<TlGlInterfaceInfo> glInterfaceHandleReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        Date businessDate = org.getToday();
        MyBatisCursorItemReader<TlGlInterfaceInfo> glInterfaceHandleCursorReader = new MyBatisCursorItemReader<>();
        glInterfaceHandleCursorReader.setSaveState(false);
        glInterfaceHandleCursorReader.setSqlSessionFactory(sqlSessionFactory);
        glInterfaceHandleCursorReader.setQueryId("com.jrx.anytxn.transaction.mapper.ext.ExtTlGlInterfaceInfoMapper.getByDateAndOrgId");
        Map<String, Object> map = new HashMap<>();
        map.put("date",businessDate);
        glInterfaceHandleCursorReader.setParameterValues(map);
        //同步reader   线程安全
        SynchronizedItemStreamReader<TlGlInterfaceInfo> synchronizedItemStreamReader = new SynchronizedItemStreamReader<>();
        synchronizedItemStreamReader.setDelegate(glInterfaceHandleCursorReader);
        return synchronizedItemStreamReader;
    }*/

    @Bean
    @StepScope
    public ItemReader<TlGlInterfaceInfo> glInterfaceHandleReader() {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        Date businessDate = org.getToday();
        return new GlInterfaceReader(businessDate,sqlSessionFactory, anytxnBatchProperties.getGlInterfaceConfig().getPageSize());
    }

}
